////
/// @group link
////

@use "sass:map";
@use "../utils";
@use "../spacing";
@use "../theme/colors";
@use "../theme/theme";
@use "../icon/icon";
@use "../interaction/interaction";
@use "../typography/typography";
@use "../transition/transition";

/// Set to `true` to disable all the styles
/// @type Boolean
$disable-everything: false !default;

/// Set to `true` to disable the `SkipToMainContent` component styles.
/// @type Boolean
$disable-skip-to-main: false !default;

/// Set to `true` to disable the `display: inline-flex` styles for the link.
/// @type Boolean
$disable-flex: false !default;

/// The transition duration for changing the link's color while hovered or
/// visited.
/// @type Number
$transition-duration: transition.$linear-duration !default;

/// The link's default text color
/// @type Color
$color: colors.$blue-500 !default;

/// The link's default visited text color
/// @type Color
$visited-color: colors.$blue-600 !default;

/// The link's default hover text color
/// @type Color
$hover-color: colors.$blue-400 !default;

/// The `z-index` for the `SkipToMainContent` component.
/// @type Number
$skip-to-main-z-index: 10000 !default;

/// A custom map of styles to apply to the `SkipToMainContent` component.
/// @type Map
$skip-to-main-styles: (
  color: theme.theme-get-var(on-primary-color),
  left: 50%,
  padding: spacing.get-var(xs) spacing.get-var(md),
  top: spacing.get-var(xs),
  transform: translateX(-50%),
  z-index: $skip-to-main-z-index,
) !default;

/// A custom map of styles to apply to the `SkipToMainContent` component while
/// it is focused. This will be applied on top of the `$skip-to-main-styles`.
///
/// @see $skip-to-main-styles
/// @type Map
$skip-to-main-active-styles: (
  outline: 0.25rem dashed currentcolor,
) !default;

/// The available configurable css variables and mostly used internally for the
/// `get-var`, `set-var`, and `use-var` utils.
/// @type List
$variables: (color, visited-color, hover-color);

/// @param {String} name - The supported variable name
/// @param {any} fallback [null] - An optional fallback value
/// @returns {String} a `var()` statement
@function get-var($name, $fallback: null) {
  $var: utils.get-var-name($variables, $name, "link");
  @if $fallback {
    @return var(#{$var}, #{$fallback});
  }

  @return var(#{$var});
}

/// @param {String} name - The supported variable name
/// @param {any} value - The value to set the variable to. Supports `null` which
/// will just be a no-op.
@mixin set-var($name, $value) {
  @if $value {
    #{utils.get-var-name($variables, $name, "link")}: #{$value};
  }
}

/// @param {String} property - The css property to apply the variable to
/// @param {String} name [$property] - The supported variable name
/// @param {any} fallback [null] - An optional fallback value if the variable
/// has not been set
@mixin use-var($property, $name: $property, $fallback: null) {
  #{$property}: get-var($name, $fallback);
}

/// Applies the light the variables based on feature flags
@mixin use-light-theme {
  @include set-var(color, $light-theme-color);
}

/// Applies the dark the variables based on feature flags
@mixin use-dark-theme {
  @include set-var(color, $dark-theme-color);
}

/// Conditionally applies the css variables based on feature flags
@mixin variables {
  @if not $disable-everything {
    @include set-var(color, $color);
    @include set-var(visited-color, $visited-color);
    @include set-var(hover-color, $hover-color);
  }
}

/// Generates all the styles based on feature flags.
///
/// @param {Boolean} disable-layer [false] - Set this to `true` to disable the
/// layer behavior
@mixin styles($disable-layer: false) {
  @if not $disable-everything {
    @include utils.optional-layer(link, $disable-layer) {
      .rmd-link {
        @include interaction.outline($outline-offset: false);
        @include use-var(color);

        transition: color $transition-duration;

        &:visited {
          @include set-var(color, get-var(visited-color));
        }

        &:hover {
          @include set-var(color, get-var(hover-color));
        }

        // can't use the normal @include interaction.surface since links are
        // rendered inline and the `::before`/`::after` pseudo selectors only work
        // nicely with block-like elements
        @if utils.$disable-focus-visible {
          @include utils.keyboard-only {
            &:focus {
              @include interaction.focus-styles($disable-background: true);
            }
          }
        } @else {
          &:focus-visible {
            @include interaction.focus-styles($disable-background: true);
          }
        }

        @if not $disable-flex {
          &--flex {
            @include icon.use-var(gap, spacing);

            align-items: center;
            display: inline-flex;
          }
        }

        @if not $disable-skip-to-main {
          &--skip {
            @include utils.map-to-styles(
              map.remove(
                typography.$headline-6-styles,
                font-size,
                font-weight,
                letter-spacing
              )
            );
            @include utils.sr-only(true, null);
          }

          &--skip-styled {
            @include utils.map-to-styles($skip-to-main-styles);

            @if utils.$disable-focus-visible {
              @include utils.keyboard-only {
                &:focus,
                &:active {
                  @include utils.map-to-styles($skip-to-main-active-styles);
                }
              }
            } @else {
              &:focus-visible {
                @include utils.map-to-styles($skip-to-main-active-styles);
              }
            }
          }
        }
      }
    }
  }
}
